<template>
  <div class="mainContainer">
    <div class="leftPanel">
      <div class="defautConfPanel">defautConfPanel</div>
      <comList
        class="comList"
        @dragStart="dragStart"
        @dragEnd="dragEnd"
        v-if="state.defaultOption.components.length"
        :defaultOption="state.defaultOption"
      ></comList>
      <div class="classList">classList</div>
    </div>
    <div class="containerBody">
      <top-panel class="topPanel"></top-panel>
      <div class="viewRegion">
        <div
          class="background com"
          :style="formSize"
          :class="state.dragging ? 'TOP' : ''"
        >
          <div v-for="(row, r) of colArr" :key="r + '_row'" class="row">
            <div
              v-for="(item, i) of new Array(24).fill(1)"
              :key="i"
              class="spanUnit"
              :_index="[r, i]"
            ></div>
          </div>
        </div>
        <formCom
          class="com"
          :style="formSize"
          :form-conf="state.formConf"
          :visible="state.showForm"
          :clickEvent="state.extendClick ? 'handleSelect' : false"
          :dragEvent="state.extendDrag ? ['dragStart', 'dragEnd'] : []"
          @handleSelect="handleSelect"
          @dragEnd="dragEnd"
          @dragStart="dragStart"
          :evalFunction="evalFunction"
          :isBind="state.isBind"
          :useIf="state.useIf"
          :key="state.formComKey"
          >></formCom
        >
        <!--
          :key="state.formComKey"
          :isCom="state.isCom"

         -->
      </div>
    </div>
    <div class="rightPanel">
      <form-panel
        class="formPanel"
        @changeFormData="changeFormData"
        @changeFormConf="changeFormConf"
      ></form-panel>
      <com-panel
        class="comPanel"
        :curCom="state.curCom"
        @changeProp="changeProp"
        >comPanel</com-panel
      >
    </div>
  </div>
</template>

<script setup lang="ts" async>
// @ts-nocheck
// eslint-disable-next-line no-extra-boolean-cast
// import { ElInput, ElRadio, ElRadioGroup } from "element-plus"
import http from "@/utils/http"
import $store from "@/stores/counter"

// import initDefaultOption from "../../../defaultOption.json"
import comList from "../../components/comList"
import {
  toCamelCase,
  deepClone,
  getCustomConfig,
  getItemByAttr,
  debounce,
  evalFunc,
  initForm
} from "../../utils/utils"
import { getTemplateByJson } from "../../utils/getTemplateByJson"
import { ElMessage } from "element-plus"
import pako from "pako"
// let test = getTemplateByJson()
// console.log(test?.replaceAll("\n", ""))
//formconf  => <template/>
const that = getCurrentInstance() //
const matchFunc = (val) => {
  const matches = val.match(/\d+/g) ?? [0]
  let nv = Number(matches.join("")) + "px"
  form.mapLayerName = nv
  return nv
}
const curSpan = ref(null)
let store = $store().state
let defaultOption = {
  form: {
    props: {
      model: {}
    },
    template: []
  },
  row: {
    props: {},
    components: []
  },
  components: []
}
const state = reactive({
  defaultOption,
  dragging: false,
  curPos: null,
  formConf: defaultOption.form,
  showForm: false,
  curCom: undefined,
  curSelect: null,
  formComKey: "22",
  panelKey: "33",
  /////////////////
  formWidth: 400,
  formHeight: 500,
  colNum: 10,
  extendClick: true,
  extendDrag: false,
  c: true,
  isLock: false,
  autoSpan: true,
  autoSave: true,
  copy: false,
  copyTemplate: false,
  clearSpan: false,
  clearOffset: false,
  saveJson: false,
  loadJson: false,
  saveDefaultForm: false,
  saveDefaultCom: false,
  isBind: false,
  useIf: true,
  saveInterval: 20,
  isCom: false
})
const formSize = computed(() => {
  return { height: state.formHeight + "px", width: state.formWidth + "px" }
})
const colArr = computed(() => {
  return new Array(state.colNum).fill(1)
})
let form = {}

const changeCol = (a) => {
  form.collapseIDs = a
}
const initFormConf = async (init = true) => {
  await http.get("getDefaultOption").then(async (res) => {
    Object.keys(state.defaultOption).forEach((k) => {
      state.defaultOption[k] = res[k] ?? state.defaultOption[k]
    })
    if (init) {
      await handleJson(false, true)
      const saveFunc = setInterval(() => {
        if (
          state.autoSave &&
          state.formConf.template?.length &&
          JSON.stringify(state.formConf) !== lastFormConf
        ) {
          // deleteEmptyRow()
          handleJson(true, true)
        }
      }, state.saveInterval * 1000)
      // state.formConf = deepClone(state.defaultOption.form)

      // ///配置不需要响应式 表单数据需要
      // state.formConf.selfIndex = "form"
      // form = state.formConf.props.model //表单数据特殊字面量
    } //else handleJson() ///！ 未知原因 刷新页面数据丢失
    else if (store.formConf) {
      // state.formConf = deepClone(store.formConf)
      // ///配置不需要响应式 表单数据需要
      // state.formConf.selfIndex = "form"
      // form = state.formConf.props.model //表单数据特殊字面量
    }
  })
}
initFormConf()
let lastFormConf = "{}"

// state.formConf = deepClone( state.defaultOption.form)
// ///配置不需要响应式 表单数据需要
// state.formConf.selfIndex = "form"
// form = state.formConf.props.model //表单数据特殊字面量
const calculateSpan = (
  para,
  propName = "selfIndex",
  queryProp = "selfIndex"
) => {
  if (para?.customType) return null
  let unitWidth = Math.floor(Number(state.formWidth) / 24)

  let dom = document.querySelector(`[${queryProp}=${para[propName]}]`)
  if (!dom) return
  let span = Math.ceil(dom?.clientWidth / unitWidth)
  return span
}
const findItem = (conf, deep = false, target = state.formConf, childProp) => {
  if (!conf.selfIndex) {
    throw new Error(JSON.stringify(conf) + "    selfIndex为空!!!")
  }
  let type = conf.selfIndex.split("_")[0]
  let item = null
  let deepObj = null
  if (type === "form") {
    item = target
  }
  if (type === "row")
    item = target.template.find((e, i) => {
      if (e.selfIndex === conf.selfIndex) {
        if (deep) {
          deepObj = [target.template, i]
        }
        return true
      }
    })
  if (!item) {
    item = getItemByAttr(
      conf.selfIndex,
      target.template,
      "selfIndex",
      childProp ?? getChildProp, ////change "components"
      true,
      deep
    )
    if (deep) deepObj = item
  }
  return deep ? deepObj : item
}
const evalFunction = eval(evalFunc.toString())
const handleDefaultOption = (param) => {
  const compressedData = pako.gzip(JSON.stringify(param))
  const headers = new Headers()
  headers.append("Content-Type", "application/json")
  headers.append("Content-Encoding", "gzip")
  Promise.all([http.post("saveDefaultOption", compressedData, headers)]).then(
    ([res0]) => {
      ElMessage.success("执行成功！")
      // store.updateDefaultOption += 1
      //  store.formConf = state.formConf
      initFormConf(false)
    }
  )
}
const deleteAttrByLoop = (attrList, obj) => {
  Object.keys(obj).forEach((k) => {
    if (attrList.indexOf(k) > -1) {
      delete obj[k]
    } else if (Array.isArray(obj[k])) {
      obj[k].forEach((e) => {
        deleteAttrByLoop(attrList, e)
      })
    }
  })
}
const saveDefaultCom = () => {
  if (!state.curCom) return
  let curIndex = store.curIndex
  let com = deepClone(state.curCom)
  deleteAttrByLoop(["parentId", "selfIndex", "belongParent"], com)

  let param = {
    option: [store.curIndex === null ? "add" : "modify", "components"],
    index: curIndex,
    param: com
  }
  handleDefaultOption(param)
}
const saveDefaultForm = () => {
  let param = {
    option: ["modify", "form"],
    param: {
      ...state.formConf,
      template: []
    }
  }
  handleDefaultOption(param)
}
const deleteDefaultCom = () => {
  let curIndex = store.curIndex
  if (curIndex === null) return
  let param = {
    option: ["delete", "components"],
    index: curIndex
    // param:state.curCom
  }
  handleDefaultOption(param)
}
// watch(
//   () => state.formConf,
//   (nv) => {
//     console.log("watch:formData", state.formConf)
//   },
//   { deep: true }
// )
const changeFormData = (val) => {
  // // formConf = deepClone(state.formConf)
  state.formConf.props.model = val
  form = state.formConf.props.model //表单数据特殊字面量
}
const changeFormConf = (val) => {
  // // formConf = deepClone(state.formConf)
  Object.keys(state.formConf).forEach((k) => {
    if (k !== "props" && k !== "template") {
      state.formConf[k] = val[k]
    }
  })
  Object.keys(val).forEach((k) => {
    if (k !== "props" && k !== "template") {
      state.formConf[k] = val[k]
    }
  })
}
const autoCalSpan = debounce((clear = false, prop = "span") => {
  let templateConf = deepClone(state.formConf.template)
  let confList = getItemByAttr(
    undefined,
    templateConf,
    "noAttr",
    getChildProp,
    false,
    false,
    [],
    true
  )
  confList.forEach((com) => {
    if (!com.comName) return
    if (clear) delete com[prop]
    else com[prop] = calculateSpan(com) || com[prop]
  })
  // templateConf.forEach((row) => {
  //   row.components.forEach((com) => {
  //   })
  // })
  state.formConf.template = templateConf
  !clear && handleSelect(state.curCom)
})
const handleSelect = (conf, parentDom) => {
  if (!conf) {
    //取消选中
    state.curCom = null
    if (state.curSelect?.className)
      state.curSelect.className =
        state.curSelect.className.replaceAll("isSelect")
    return
  }
  // form = state.formConf.props.model
  if (!parentDom)
    parentDom = document.querySelector(`[eventObj=${conf.selfIndex}]`)
  if (!parentDom) return
  let item = null
  item = findItem(conf, false)
  if (state.curSelect?.className)
    state.curSelect.className = state.curSelect.className.replaceAll(
      "isSelect",
      ""
    )
  if (item) {
    state.curCom = item
    state.curSelect = parentDom
    if (!state.curSelect.className) state.curSelect.className = ""
    state.curSelect.className += " isSelect"
  }
}
const deleteEmptyRow = () => {
  return //！重写！！！！
  let templateConf = deepClone(state.formConf.template)
  let rowList = getItemByAttr(
    (val) => val && !val.length,
    templateConf,
    "components",
    getChildProp,
    false,
    true,
    [],
    true
  )
  rowList.forEach((r) => {
    delete r[0][r[1]]
  })
  function removeNullElements(arr) {
    for (let i = 0; i < arr.length; i++) {
      if (!arr[i]) {
        arr.splice(i, 1) // Remove the null element
        i-- // Decrement i to account for the removed element
      } else {
        let prop = getChildProp(arr[i])
        if (Array.isArray(arr[i][prop])) {
          removeNullElements(arr[i][prop]) // Recurse into nested array
        }
      }
    }
    return arr
  }
  state.formConf.template = removeNullElements(templateConf) //改为真实数组长度
}
const copyToClipboard = (str) => {
  const el = document.createElement("textarea")
  el.value = str
  document.body.appendChild(el)
  el.select()
  document.execCommand("copy")
  document.body.removeChild(el)
}
const handleJson = (isSave = false, isLast = false) => {
  let api = isSave
    ? isLast
      ? "saveLastJson"
      : "saveJson"
    : isLast
    ? "getLastJson"
    : "getJson"
  if (isSave) {
    const compressedData = pako.gzip(JSON.stringify(state.formConf))
    const headers = new Headers()
    headers.append("Content-Type", "application/json")
    headers.append("Content-Encoding", "gzip")
    http.post(api, compressedData, headers).then((res) => {
      !isLast && ElMessage.success("保存成功!")
    })
  } else {
    http.get(api).then((res) => {
      if (res == {}) {
        state.showForm = true
        return
      }
      state.formConf = {
        ...res,
        template: res.template ? markRaw(res.template) : undefined
      }
      //判断是否渲染组件
      state.isCom = !Array.isArray(res.template)
      form = state.formConf.props.model //表单数据特殊字面量
      state.showForm = true
      ElMessage.success("加载成功!")
      watch(
        () => state.isCom,
        () => {
          state.showForm = false
          if (!state.isCom) {
            let nform
            if (state.lastFormConf) {
              nform = deepClone(state.lastFormConf)
            } else {
              nform = deepClone(state.defaultOption.form)
              nform.template = [deepClone(state.defaultOption.row)]
              nform.template[0].components = [
                deepClone(state.formConf.template)
              ]
            }
            state.formConf.template = markRaw(nform.template)
          } else {
            let com = state.curCom ?? state.defaultOption.components[0]
            state.lastFormConf = markRaw(deepClone(state.formConf))
            state.formConf.template = markRaw(com)
          }
          state.formComKey += 1
          state.showForm = true
        }
      )
    })
  }
}

watch(
  () => state.isLock,
  (nv) => {
    if (nv) {
      state.extendClick = false
      state.extendDrag = false
      handleSelect(null)
    }
  }
)
watch(
  () => state.copy,
  () => {
    deleteEmptyRow()
    copyToClipboard(JSON.stringify(state.formConf))
    ElMessage.success("已复制!")
  }
)
watch(
  () => state.copyTemplate,
  () => {
    deleteEmptyRow()
    let json = deepClone(state.curCom ?? state.formConf)
    let str = getTemplateByJson({ json })
    debugger
    copyToClipboard(str)
    ElMessage.success("已复制!")
  }
)
watch(
  () => state.extendClick,
  (nv) => {
    if (!nv) {
      handleSelect(null)
    }
  }
)
watch(
  () => state.clearSpan,
  () => {
    autoCalSpan(true)
  }
)
watch(
  () => state.saveJson,
  () => {
    deleteEmptyRow()
    handleJson(true)
  }
)
watch(
  () => state.loadJson,
  () => {
    handleJson()
  }
)
watch(
  () => state.clearOffset,
  () => {
    autoCalSpan(true, "offset")
  }
)
/* watch(
  () => state?.formConf?.props?.model,
  (nv) => {
    console.log("formdataChange:", nv)

    form = nv
  },
  { deep: true }
) */
form = eval(initForm.replaceAll("{formConfStr}", "state.formConf"))

watch(
  () => state.formWidth,
  (nv) => {
    if (state.autoSpan) autoCalSpan()
  }
)
watch(
  () => state.autoSpan,
  (nv) => {
    if (nv) autoCalSpan()
  }
)
watch(
  () => store.deleteDefaultCom,
  (nv) => {
    deleteDefaultCom()
    store.curIndex = null
  }
)
watch(
  () => state.saveDefaultForm,
  (nv) => {
    saveDefaultForm()
  }
)
watch(
  () => state.saveDefaultCom,
  (nv) => {
    deleteEmptyRow()
    saveDefaultCom()
  }
)
/* watchEffect(() => {
  console.log("effect,formdata")

  form = state.formConf.props.model
}) */
const changeProp = (conf) => {
  // if (!state.curCom) return
  state.showForm = false
  let item = null
  // item = findItem(conf, true, state.formConf)
  item = getItemByAttr(
    conf.selfIndex,
    state.formConf.template,
    "selfIndex",
    getChildProp,
    true,
    true
  )
  item?.length && (item[0][item[1]] = deepClone(conf))
  if (state.curCom) {
    //更新curcom
    let n = getItemByAttr(
      state.curCom.selfIndex,
      state.formConf.template,
      "selfIndex",
      getChildProp,
      true,
      true
    )
    state.curCom = n?.length ? n[0][n[1]] : null
  } //change
  // state.curCom = item[0][item[1]] = conf
  // formConf = deepClone(state.formConf)
  // formConf.props.model = state.formConf.props.model
  //////////////////CHANGE
  state.showForm = true
}
const getChildProp = (item, i, arr) => {
  let list = ["template", "components", "childNode"]
  if (!item) return undefined
  let e = list.find((prop) => {
    if (item[prop]?.length && Array.isArray(item[prop])) return true
  })

  // if (!item.selfIndex) return "template"
  try {
    if (item.selfIndex.startsWith("row")) return "components"
    return e ?? "childNode"
  } catch (error) {}
}
// const overSpanUnit = (e) => {
//   let pos = e.target?.attributes?._index?.value
//   if (pos) state.curPos = pos
// }
// const leaveSpanUnit = (e) => {
//   state.curPos = null
// }
const getRowByDom = (dom) => {
  let flg = (e) => {
    // return e?.attributes?.selfIndex?.value?.includes("row_")
    if (!e?.className) return false
    return e?.className?.includes("el-row")
  }
  let rowDom = getUnitDom(dom, flg)
  let selfIndex = rowDom?.attributes?.selfIndex?.value
  if (!selfIndex) return null
  let rowConf = findItem({ selfIndex }, false, undefined, getChildProp)
  return rowConf
}
const getUnitDom = (e, flg, loop = 0) => {
  if (flg(e)) {
    return e
  } else {
    loop += 1
    if (loop > 8) return null
    if (!e?.parentNode) {
      return null
    }
    return getUnitDom(e.parentNode, flg, loop)
  }
}
const dragEnd = (comName, curDom, changePosition = false, elPos) => {
  state.dragging = true
  changeContainerStyle(false)
  let rowConf = getRowByDom(curDom)
  setTimeout(() => {
    let cspan = document.elementFromPoint(elPos[0], elPos[1])
    state.dragging = false
    if (!cspan?.className?.includes("spanUnit")) return
    state.curPos = cspan?.attributes?._index?.value

    if (!changePosition) {
      if (state.curPos) createCom(comName, undefined, rowConf)
    } else {
      let item = findItem(
        { selfIndex: comName },
        true,
        state.formConf,
        getChildProp
      )
      if (item && Array.isArray(item)) {
        let curCom = item[0][item[1]]
        if (curCom && state.curPos) {
          removeCom(item)
          createCom(curCom, undefined, rowConf)
        }
      }
    }
    state.curPos = null
  }, 100)
}
const removeCom = ([arr, index]) => {
  if (index !== arr.length - 1) {
    arr[index + 1].offset =
      (arr[index + 1]?.offset ?? 0) +
      (arr[index]?.offset ?? 0) +
      (arr[index]?.span ?? 0)
  }
  arr.splice(index, 1)
}
const dragStart = () => {
  changeContainerStyle(true)
  ///////其他容器显示边界
  // document.querySelector(`[${queryProp}=${para[propName]}]`)
}
const changeContainerStyle = (isDrag = true) => {
  let domList = document.querySelectorAll(`.isComContainer`)
  if (!domList?.length) return
  domList.forEach((e) => {
    if (isDrag) e.className += " containerDragging"
    else e.className = e.className.replaceAll("containerDragging", "")
  })
}

const initRow = (para) => {
  let rowConf = deepClone(state.defaultOption.row)
  Object.assign(rowConf, para)
  rowConf.selfIndex = "row_" + Math.ceil(Math.random() * 10 ** 6) ///id
  return rowConf
}
const initComChild = (para: Object) => {
  let item = state.defaultOption.components.find((e) => {
    if (e.comName === para.comName) {
      return true
    }
  })
  let child = {}
  if (item.childNode.length) {
    Object.assign(child, deepClone(item.childNode[0]))
  } else {
    Object.assign(child, { comName: "div" })
  }
  child.selfIndex = child.comName + "_" + Math.ceil(Math.random() * 10 ** 6)
  return child
}
const getComType = (e) => {
  if (!e.customType) return null
  if (e.customType.includes("col")) return "col"
  if (e.customType.includes("row")) return "row"
  return "form"
}
const setBelongByLoop = (comConf, childProp = getChildProp) => {
  if (getComType(comConf) && getComType(comConf) !== "col") {
    //comConf.span = 24
    //comConf.offset = 0

    let confList = getItemByAttr(
      undefined,
      Array.isArray(comConf.template) ? comConf.template : comConf.childNode,
      "noAttr",
      getChildProp,
      false,
      false,
      [],
      true
    )
    confList.forEach((e) => {
      e.comName && (e.belongParent = comConf.selfIndex)
      //递归为子元素添加父元素标识
    })
  }
  let cprop = childProp
  if (typeof childProp === "function") cprop = childProp(comConf)
  if (Array.isArray(comConf[cprop])) {
    comConf[cprop].forEach((e) => {
      setBelongByLoop(e)
    })
  }

  ////!change
}
const initCom = (para: Object) => {
  let item = state.defaultOption.components.find((e) => {
    if (e.comName === toCamelCase(para.comName)) {
      return true
    }
  })
  let comConf = {}
  if (item && !para.parentId) {
    Object.assign(comConf, deepClone(item), deepClone(para))
  } else Object.assign(comConf, deepClone(para)) ///////change
  comConf.comName = toCamelCase(comConf.comName)
  comConf.selfIndex =
    comConf.selfIndex ??
    comConf.comName + "_" + Math.ceil(Math.random() * 10 ** 6) ///id
  setChildrenIndex(comConf)
  if (!comConf.span && comConf.parentId) {
    comConf.span = calculateSpan(comConf, "parentId", "parentId")

    delete comConf["parentId"]
  }
  //setBelongByLoop(comConf)

  return comConf
}
const setChildrenIndex = (e, propName = "childNode", belongParent) => {
  propName = getChildProp(e)
  let comConf = e

  if (getComType(comConf) && getComType(comConf) !== "col") {
    belongParent = comConf.selfIndex
  }
  try {
    let arr = e[propName]
    if (Array.isArray(arr) && arr.length) {
      arr.forEach((ee) => {
        if (!ee.selfIndex)
          ee.selfIndex =
            (ee.comName ?? "row") + "_" + Math.ceil(Math.random() * 10 ** 6)
        ee.belongParent = belongParent
        setChildrenIndex(ee, undefined, belongParent)
      })
    }
  } catch (error) {
    throw error
  }
}
const createCom = (para, isSelect = true, rowConf = undefined) => {
  state.showForm = false
  let parent = state.formConf
  let belongParent, slotName
  if (para.belongParent) {
    //自定义组件嵌套时 无法识别
    parent =
      findItem(
        { selfIndex: para.belongParent },
        false,
        undefined,
        getChildProp
      ) ?? parent

    belongParent = para.belongParent
    slotName = parent.slotNames?.length ? parent.slotNames[0] : undefined
  }

  if (!parent) return //initFormConf()
  if (!state.curPos) return
  let newcom = null
  let [rowIndex, span] = state.curPos.split(",").map((e) => Number(e))
  let hasRow = true
  if (!rowConf) {
    rowConf = initRow({ slotName })

    hasRow = false
  }
  let coms = rowConf?.components
  try {
    if (coms?.length) {
      let offsetLeft = 0
      for (let c in coms) {
        let com = coms[c]
        let beforeCom = c == 0 ? null : coms[c - 1]
        // if (!com.offsetLeft) {
        // }
        if (com.offset + offsetLeft + (beforeCom?.span || 0) > span) {
          //距左侧距离 插入
          let offset = span - offsetLeft - (beforeCom?.span || 0)
          newcom = initCom({ ...para, offset, belongParent })
          coms.splice(c, 0, newcom)
          if (c !== coms.length - 1) {
            let afterCom = com
            let nf =
              afterCom.offset - (newcom?.offset ?? 0) - (newcom?.span ?? 0)
            afterCom.offset = nf > 0 ? nf : 0
          }
          break
        } else {
          offsetLeft = com.offset + offsetLeft + (beforeCom?.span || 0) //+com.span
          if (c == coms.length - 1) {
            let offset = span - offsetLeft - (com?.span || 0)
            newcom = initCom({ ...para, offset, belongParent })
            coms.push(newcom)
          }
        }
      }
    } else {
      newcom = initCom({ ...para, offset: span, belongParent })
      coms.push(newcom)
    }
  } catch (error) {}
  if (!hasRow) {
    let ri = null
    let r = parent.template.find((e, i) => {
      if (e.components?.length) {
        ri = i
        return true
      }
    })
    if (ri) {
      parent.template[ri] = rowConf
    } else parent.template.push(rowConf)
  }
  // for (let i = 0; i <= rowIndex; i++) {
  //   if (!parent.template[i]) {
  //     parent.template[i] = initRow({ slotName })
  //   }
  //   if (i !== rowIndex) continue
  //   let coms = parent.template[i].components
  //   if (coms.length) {
  //     let offsetLeft = 0
  //     for (let c in coms) {
  //       let com = coms[c]
  //       let beforeCom = c == 0 ? null : coms[c - 1]
  //       // if (!com.offsetLeft) {
  //       // }
  //       if (com.offset + offsetLeft + (beforeCom?.span || 0) > span) {
  //         //距左侧距离 插入
  //         let offset = span - offsetLeft - (beforeCom?.span || 0)
  //         newcom = initCom({ ...para, offset, belongParent })
  //         coms.splice(c, 0, newcom)
  //         if (c !== coms.length - 1) {
  //           let afterCom = com
  //           let nf =
  //             afterCom.offset - (newcom?.offset ?? 0) - (newcom?.span ?? 0)
  //           afterCom.offset = nf > 0 ? nf : 0
  //         }
  //         break
  //       } else {
  //         offsetLeft = com.offset + offsetLeft + (beforeCom?.span || 0) //+com.span
  //         if (c == coms.length - 1) {
  //           let offset = span - offsetLeft - (com?.span || 0)
  //           newcom = initCom({ ...para, offset, belongParent })
  //           coms.push(newcom)
  //         }
  //       }
  //     }
  //   } else {
  //     newcom = initCom({ ...para, offset: span, belongParent })
  //     coms.push(newcom)
  //   }
  // }

  state.showForm = true
  if (isSelect && newcom) nextTick(() => handleSelect(newcom))
}
provide("model", () => state.formConf.props.model)
provide("state", state)
provide("findItem", findItem)
provide("createCom", createCom)
provide("removeCom", removeCom)
provide("initRow", initRow)
provide("initCom", initCom)
provide("getChildProp", getChildProp)
provide("initComChild", initComChild)
provide("handleSelect", handleSelect)
</script>
<style lang="less">
.comContainer {
  min-width: 44px;
  min-height: 22px;
  border: 1px dashed #8f84849c;
  .el-form-item {
    margin-bottom: 0 !important;
  }
}
/deep/span.textPanel {
  font-size: 12px;
  cursor: pointer;
  color: aqua;
}
</style>
<style lang="less" scoped>
.fullContent() {
  width: 100%;
  height: 100%;
}
.flexNormal() {
  width: 100%;
  height: 100%;
  display: flex;
}
.mainContainer {
  .flexNormal();
  .leftPanel {
    width: 320px;
    height: 100%;
    display: flex;
    flex-direction: column;
    .defautConfPanel {
      height: 180px;
      border-right: 1px solid pink;
    }
    .comList {
      flex: 1;
      // overflow-y: auto;
      background: #ebe7e5;
    }
    .classList {
      height: 200px;
      border-right: 1px solid pink;
    }
  }
  .rightPanel {
    .flexNormal();
    width: 520px;
    flex-direction: column;
    .formPanel {
      height: 260px;
    }
    .comPanel {
      flex: 1;
    }
    .codePanel {
      height: 220px;
    }
  }
  .topPanel {
    height: 120px;
    width: 100%;
  }

  .containerBody {
    .flexNormal();
    flex: 1;
    flex-direction: column;
    .viewRegion {
      // overflow-x: scroll;
      max-width: calc(100% - 10px) !important;
      flex: 1;
      margin: 5px;
      position: relative;
      .com {
        &.background {
          z-index: 2;
          background: #beccd9;
          flex-direction: column;
          .flexNormal();
          .row {
            flex: 1;
            .flexNormal();
            &:nth-child(2n) {
              opacity: 0.47;
            }
            .spanUnit {
              flex: 1;
              background: #adcee5;
              &:nth-child(2n) {
                background: #d6dee3;
              }
              &.isHover {
                background: rgb(7, 32, 80) !important;
                opacity: 0.8 !important;
              }
            }
          }
        }
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        z-index: 20;
        overflow-y: auto;
      }
    }
  }
}
.TOP {
  z-index: 30 !important;
  opacity: 0.4 !important;
}
</style>
